import CodeView from '../../../shared/components/CodeView';
import CodeBlock from '../../../shared/components/CodeBlock';
import Blockquote from '../../../shared/components/Blockquote';
import { getDisplayElementById, getDemoStylesById } from '../../shared/helpers';
import * as SimpleTableExamples from './base/example';
import * as AdvancedTableExamples from './advanced/example';
import * as InlineEditTableExamples from './inline-edit/example';

<div className="doc lead">
Data tables are an enhanced version of an HTML table and are used to display tabular data.
</div>

<CodeView exampleOnly demoStyles="overflow: hidden;">
  {getDisplayElementById(AdvancedTableExamples.states, 'actionable-mode')}
</CodeView>

## About Data Tables

To initialize a data table, apply the `slds-table` class to the `table` element. This class creates a `table` with formatted cells and allows you to use data table utilities.

### Accessibility

#### Headers
To create an accessible table, the top row of column headers (`th`) are placed in a `thead`. Each one receives the `scope="col"` attribute. The first non-actionable (meaning that doesn't contain a checkbox or menu) column in each row should be marked as a th with a `scope="row"` attribute.

#### Labeling
To give additional context, like a caption or description, to a table for screen readers, the attributes `aria-labelledby` or `aria-label` can be used on the `table` element.

For `aria-label`, set the description as the attribute value.  Alternatively, if another element, or elements, can serve this purpose for the table, then set the value of `aria-labelledby` with the `id` of the element[s].

This example shows `aria-labelledby` set with the `id`s of two separate elements to make up the label.

<CodeView>
  {getDisplayElementById(SimpleTableExamples.examples, 'data-table-aria-labelledby')}
</CodeView>


## Base

<CodeView>
  {getDisplayElementById(SimpleTableExamples.default)}
</CodeView>

### Striped rows

<CodeView>
  {getDisplayElementById(SimpleTableExamples.examples, 'data-table-striped-rows')}
</CodeView>

### Columns dividers

<CodeView>
  {getDisplayElementById(SimpleTableExamples.examples, 'data-table-vertical-borders')}
</CodeView>

### Rows with no hover

<CodeView>
  {getDisplayElementById(SimpleTableExamples.examples, 'data-table-no-hover')}
</CodeView>

### Single Column table

<CodeView>
  {getDisplayElementById(SimpleTableExamples.examples, 'single-column')}
</CodeView>

### Headless

<CodeView>
  {getDisplayElementById(SimpleTableExamples.examples, 'headless')}
</CodeView>

#### With no borders

<CodeView>
  {getDisplayElementById(SimpleTableExamples.examples, 'headless-no-borders')}
</CodeView>

## Actionable mode - Column sorting and row selection(s)

<CodeView demoStyles="overflow: hidden;">
  {getDisplayElementById(AdvancedTableExamples.states, 'actionable-mode')}
</CodeView>

### Single row selection

<CodeView demoStyles="overflow: hidden;">
  {getDisplayElementById(AdvancedTableExamples.examples, 'radio-group')}
</CodeView>

### Navigation mode - Cell focused

<CodeView demoStyles="overflow: hidden;">
  {getDisplayElementById(AdvancedTableExamples.states, 'cell-focused')}
</CodeView>

### Row Selection

#### Single row selected

<CodeView demoStyles="overflow: hidden;">
  {getDisplayElementById(AdvancedTableExamples.states, 'row-selected')}
</CodeView>

#### All rows selected

<CodeView demoStyles="overflow: hidden;">
  {getDisplayElementById(AdvancedTableExamples.states, 'all-row-selected')}
</CodeView>

### Column sorting

<Blockquote type="a11y" header="Accessibility Note">
  <p>
    The assistive text for the sort action contains `aria-live="polite"` so screen
    reader doesn't disrupt itself from announcing what the user is interacting with.
  </p>
</Blockquote>

#### Sorted Ascending

<CodeView demoStyles="overflow: hidden;">
  {getDisplayElementById(AdvancedTableExamples.states, 'sorted-column-asc')}
</CodeView>

#### Sorted Descending

<CodeView demoStyles="overflow: hidden;">
  {getDisplayElementById(AdvancedTableExamples.states, 'sorted-column-desc')}
</CodeView>

### Column resizing

<CodeView demoStyles="overflow: hidden;">
  {getDisplayElementById(AdvancedTableExamples.states, 'resized-column')}
</CodeView>

### Column headers with overflow actions button menu

<CodeView demoStyles="overflow: hidden;">
  {getDisplayElementById(AdvancedTableExamples.examples, 'header-menu-button')}
</CodeView>

### Column with icons

<CodeView demoStyles="overflow: hidden;">
  {getDisplayElementById(AdvancedTableExamples.examples, 'header-icon-menu-button')}
</CodeView>

### Cell with icons

<CodeView demoStyles="overflow: hidden;">
  {getDisplayElementById(AdvancedTableExamples.examples, 'cell-icon')}
</CodeView>

## Inline Edit

### Accessibility

The Advanced Data Table and Inline Edit Data Table are based on the semantics, roles and interaction model of the ARIA Grid. In SLDS we overlay the [ARIA Grid](http://w3c.github.io/aria/practices/aria-practices.html#grid) on top of native HTML table semantics.

The role of Grid comes with 2 distinct modes, Navigation mode and Actionable mode. Both come with very specific keyboard interaction modals. Navigation mode is the default mode of the Grid.

Bold text for edited cell examples provide secondary indicators for text, along with yellow backgrounds, to indicate content is edited but unsaved.

**Navigation Mode**

- Tabbing into the grid focuses the first data cell in the table.
- The second tab key press takes the user focus out of the grid onto the next focusable element on the page.
- Once the user has tabbed out of the grid, tabbing back into the grid will return focus to the last cell the user was focused on.
- Navigation in the grid is accomplished via the arrow keys.
- No actionable items in cell contents are focusable.
- Pressing the Enter key on a chosen grid cell, places the entire Grid into Actionable mode.

**Actionable Mode**

- Once in Actionable mode, all focusable items in the entire grid can be tabbed to.
- Arrow navigation still takes the user cell to cell in any direction, but focuses on the first actionable item in the cell, if there is one.
- Pressing the Escape key exits Actionable mode, placing the user back into Navigation mode, keeping the users cursor on the same cell they were focused in.
- When interacting with a component in a cell, such as a Menu, that also uses the Escape key as an exit action, pressing Escape will take the user back to the triggering element in the current cell. A subsequent press of Escape will return the user to Navigation mode.

For the purposes of these docs, the Default state of Inline Edit is representative of Navigation mode, all other states are assumed to be in Actionable Mode.

<CodeView demoStyles="overflow: hidden;">
  {getDisplayElementById(InlineEditTableExamples.default)}
</CodeView>

### Keyboard navigation

#### 1st cell highlighted (checkbox)

<CodeView demoStyles="overflow: hidden;">
  {getDisplayElementById(InlineEditTableExamples.states, 'checkbox')}
</CodeView>

#### 2nd cell highlighted

<CodeView demoStyles="overflow: hidden;">
  {getDisplayElementById(InlineEditTableExamples.states, 'with-link')}
</CodeView>

#### 3rd cell highlighted

<CodeView demoStyles="overflow: hidden;">
  {getDisplayElementById(InlineEditTableExamples.states, 'focused')}
</CodeView>

### Cell Edit

<CodeView demoStyles="overflow: hidden;">
  {getDisplayElementById(InlineEditTableExamples.states, 'edit')}
</CodeView>

#### Required form element

<CodeView demoStyles="overflow: hidden;">
  {getDisplayElementById(InlineEditTableExamples.states, 'required')}
</CodeView>

#### Required form element with error

<CodeView demoStyles="overflow: hidden;">
  {getDisplayElementById(InlineEditTableExamples.states, 'error')}
</CodeView>

#### Edited cell (unsaved)

<CodeView demoStyles="overflow: hidden;">
  {getDisplayElementById(InlineEditTableExamples.states, 'edited')}
</CodeView>

#### Edited cell with row selected (unsaved)

<CodeView demoStyles="overflow: hidden;">
  {getDisplayElementById(InlineEditTableExamples.states, 'row-selected-with-edited-cell')}
</CodeView>

#### Edited cell with row level error (unsaved)

<CodeView demoStyles="overflow: hidden;">
  {getDisplayElementById(InlineEditTableExamples.states, 'row-error')}
</CodeView>

#### Edited cell with focused row level error  (unsaved)

<CodeView demoStyles="overflow: hidden;">
  {getDisplayElementById(InlineEditTableExamples.states, 'row-error-focused')}
</CodeView>

#### Edited cell with row selected and row level error (unsaved)

<CodeView demoStyles="overflow: hidden;">
  {getDisplayElementById(InlineEditTableExamples.states, 'row-error-and-selected')}
</CodeView>

### Header navigation

#### Header cell focused

<CodeView demoStyles="overflow: hidden;">
  {getDisplayElementById(InlineEditTableExamples.states, 'header-cell-focused')}
</CodeView>

#### Header cell marked

<CodeView demoStyles="overflow: hidden;">
  {getDisplayElementById(InlineEditTableExamples.states, 'header-cell-marked')}
</CodeView>

### Cell Content

As a default method, wrap any table cell content in a `<div>`.

#### Truncated

Add the `slds-truncate` class to truncate any content that might overflow the tables cell area.

<CodeView demoStyles={getDemoStylesById(SimpleTableExamples.examples, 'cell-content-truncated')}>
  {getDisplayElementById(SimpleTableExamples.examples, 'cell-content-truncated')}
</CodeView>

#### Wrapped

In those cases where long cell content is anticipated, use the `slds-cell-wrap` class on the cell `<td>` to have the text wrap within the cell’s width.

Also, use the `slds-line-clamp` class on the content-wrapping `<div>` to clamp, or truncate, the cell content after a certain amount of lines. Other [line clamping classes](/utilities/line-clamp) can be used in place for various line clamping limits. The clamping limit can also be changed by reassigning a value to the `line-clamp` token.

<CodeView demoStyles={getDemoStylesById(SimpleTableExamples.examples, 'cell-content-wrapped')}>
  {getDisplayElementById(SimpleTableExamples.examples, 'cell-content-wrapped')}
</CodeView>
